package map.abstractor.xaml2uimodel;

import java.io.BufferedWriter;
import java.io.IOException;

import map.abstractor.xaml2uimodel.base.XMLDocument;
import map.abstractor.xaml2uimodel.base.XamlElement;
import map.abstractor.xaml2uimodel.base.XamlProperty;
import map.abstractor.xaml2uimodel.visitors.XamlVisitor;
import map.abstractor.xmlmodel.ChildElement;
import map.abstractor.xmlmodel.Property;
import map.abstractor.xmlmodel.RootElement;
import map.abstractor.xmlmodel.XMLObject;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Xaml2XMLModelVisitor extends XamlVisitor {

	/**
	 * Constants
	 */
	public final String Xmlheader = "<?xml version=\"1.0\" encoding=\"ASCII\"?>\n";

	/**
	 * Fields
	 */
	private BufferedWriter out = null;
	private XMLObject root = null;
	
	/**
	 * Constructors
	 */
	public Xaml2XMLModelVisitor(String xsd) {
		this(xsd,null,false,false);
	}
	
	public Xaml2XMLModelVisitor(String xsd, BufferedWriter output) {
		this(xsd,output,false,false);
	}
		
	public Xaml2XMLModelVisitor(String xsd, BufferedWriter output, boolean withLayout){
		this(xsd,output,withLayout,false);
	}
	
	public Xaml2XMLModelVisitor(String xsd, BufferedWriter output, boolean withLayout, boolean widthStyle){
		this.out = output;
		this.root = null;
	}
	

	public XMLObject visit(XMLDocument doc) {
		
		NamedNodeMap n=doc.getElement().getAttributes();
		root = new RootElement();
		ChildElement child= new ChildElement(doc.getElement().getTagName());
		root.addChild(child);
		for(int i=0; i<n.getLength(); i++){
			Property p= new Property(n.item(i).getNodeName(),n.item(i).getNodeValue());
			child.addChild(p);
		}

		if(doc.getElement().getChildNodes()!=null){
			NodeList nl=doc.getElement().getChildNodes();
			for(int i=0; i<nl.getLength();i++){
				Node node=doc.getElement().getChildNodes().item(i);
				
				visit( node, child);
			}
		}
		if (out != null)
			try {
				out.write(Xmlheader + root.toString(0));
			} catch (IOException e) {
				e.printStackTrace();
			}
		return root;
	}

	@Override
	public XMLObject visit(Node node, Object container) {
		XamlElement element= new XamlElement(node);
		//System.out.println("XamlElement "+node.getNodeValue()+ " "+ element.getTag());
		ChildElement child= null;
		if(!((XamlElement)element).getTag().startsWith("#")){
			child=new ChildElement(((XamlElement)element).getTag());
			for(XamlProperty prop: element.getProperties() ){
				Property p= new Property(prop.getTag(),prop.getValue());
				child.addChild(p);
			}
			((XMLObject)container).addChild(child);
			int nl=node.getChildNodes().getLength();
			if(nl!=0)
				for(int i=0; i<nl; i++)
				{
					Node ni= node.getChildNodes().item(i);
					if(ni.getNodeValue()!=null && ni.getNodeValue().trim().length()>0)
					{
						Property p= new Property("Content",ni.getNodeValue());
						child.addChild(p);

					}
					visit(node.getChildNodes().item(i),child);
				}
		}
		return child;
	}
}
